﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace CircumferenceRotatePanelControl
{
    public class CircumferenceRotatePanel2 : Canvas
    {
        public CircumferenceRotatePanel2()
        {
            Thread thread = new Thread(OnShowMenu);
            thread.IsBackground = true;
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

        #region >>DP

        /// <summary>
        /// 自定义是否显示菜单区域
        /// </summary>
        public static readonly DependencyProperty ShowMenuProperty = DependencyProperty.Register(
            "ShowMenu",
            typeof(bool),
            typeof(CircumferenceRotatePanel2),
            new PropertyMetadata(default(bool))
        );

        //自定义显示旋转圈数
        public static readonly DependencyProperty RotateNoumberProperty =
            DependencyProperty.Register(
                "RotateNoumber",
                typeof(double),
                typeof(CircumferenceRotatePanel2),
                new PropertyMetadata(default(double))
            );

        //自定义旋转速度
        public static readonly DependencyProperty RotateSpeedProperty = DependencyProperty.Register(
            "RotateSpeed",
            typeof(double),
            typeof(CircumferenceRotatePanel2),
            new PropertyMetadata(default(double))
        );

        //自定义鼠标操作还是触屏操作
        public enum OperateEnum
        {
            MouseOperate,
            TouchuOperate,
        }

        public static readonly DependencyProperty OperateTypeProperty = DependencyProperty.Register(
            "OperateType",
            typeof(OperateEnum),
            typeof(CircumferenceRotatePanel2),
            new PropertyMetadata(default(OperateEnum))
        );

        //自定义图标宽和高
        public static readonly DependencyProperty IconWidthAndHeightProperty =
            DependencyProperty.Register(
                "IconWidthAndHeight",
                typeof(double),
                typeof(CircumferenceRotatePanel2),
                new PropertyMetadata(default(double))
            );

        #endregion

        #region >>属性
        [Description("*自定义是否显示菜单区域")]
        public bool ShowMenu
        {
            get { return (bool)GetValue(ShowMenuProperty); }
            set { SetValue(ShowMenuProperty, value); }
        }

        [Description("*自定义旋转度数")]
        public double RotateNoumber
        {
            get { return (double)GetValue(RotateNoumberProperty); }
            set { SetValue(RotateNoumberProperty, value); }
        }

        [Description("*自定义旋转速度")]
        public double RotateSpeed
        {
            get { return (double)GetValue(RotateSpeedProperty); }
            set { SetValue(RotateSpeedProperty, value); }
        }

        [Description("*自定义操作方式")]
        public OperateEnum OperateType
        {
            get { return (OperateEnum)GetValue(OperateTypeProperty); }
            set { SetValue(OperateTypeProperty, value); }
        }

        [Description("*自定义图标宽高")]
        public double IconWidthAndHeight
        {
            get { return (double)GetValue(IconWidthAndHeightProperty); }
            set { SetValue(IconWidthAndHeightProperty, value); }
        }


        #endregion

        public List<CircumferenceItem> circumferenceItems = [];

        #region >>自定义方法
        //线程处理
        private void OnShowMenu()
        {
            this.Dispatcher.Invoke(
                new Action(
                    delegate
                    {
                        //若显示中间图标
                        DivideCircleOnShowMenu();
                        FrameworkElement fp = this.Parent as FrameworkElement;
                        if (OperateType == OperateEnum.MouseOperate)
                        {
                            this.MouseDown += Rotate_MouseDown;
                            fp.MouseUp += Fp_MouseUp;
                        }
                        else
                        {
                            this.TouchDown += Fotate_TouchDown;
                            fp.TouchUp += Rotate_TouchUp;
                        }
                        centerP.X = this.Width / 2;
                        centerP.Y = this.Height / 2;

                        int iconCount = this.Children.Count - 1; // 排除中心图标
                        double angleStep = 2 * Math.PI / iconCount;

                        baseAngles.Clear();
                        for (int i = 1; i < this.Children.Count; i++)
                        {
                            baseAngles.Add((i - 1) * angleStep);
                        }

                        AddLine();

                    }
                )
            );
        }
        int circleRadius = 80;
        private void AddLine()
        {
            UIElementCollection children = this.Children;

            // 获取中心图标
            FrameworkElement centerElement = children[0] as FrameworkElement;
            double centerX = Canvas.GetLeft(centerElement) + centerElement.Width / 2;
            double centerY = Canvas.GetTop(centerElement) + centerElement.Height / 2;
            var count = children.Count;

            // 添加一个公共圆圈
            Ellipse commonCircle = new Ellipse
            {
                Width = circleRadius * 2,
                Height = circleRadius * 2,
                Stroke = Brushes.Black,
                StrokeThickness = 2,
                Fill = Brushes.Transparent,
                Tag = "yuan"
            };
            Canvas.SetLeft(commonCircle, centerX - circleRadius);
            Canvas.SetTop(commonCircle, centerY - circleRadius);
            this.Children.Add(commonCircle);

            for (int i = 1; i < count; i++)
            {
                FrameworkElement f = children[i] as FrameworkElement;
                if (f == null || f.Visibility != Visibility.Visible)
                    continue;

                // 获取目标图标的中心点
                double iconX = Canvas.GetLeft(f) + f.Width / 2;
                double iconY = Canvas.GetTop(f) + f.Height / 2;

                // 计算方向向量
                double dx = iconX - centerX;
                double dy = iconY - centerY;

                // 计算圆周上的中断点
                Point midPointOnCircle = GetPointOnCircle(centerX, centerY, circleRadius, dx, dy);



                // 绘制从中断点到目标点的线段
                Line lineFromMid = new Line
                {
                    X1 = midPointOnCircle.X,
                    Y1 = midPointOnCircle.Y,
                    X2 = iconX,
                    Y2 = iconY,
                    Stroke = Brushes.Black,
                    StrokeThickness = 2,
                    Tag = f
                };
                this.Children.Add(lineFromMid);
            }
        }

        private Point GetPointOnCircle(double centerX, double centerY, double radius, double dx, double dy)
        {
            // 计算单位方向向量
            double length = Math.Sqrt(dx * dx + dy * dy);
            double unitDx = dx / length;
            double unitDy = dy / length;

            // 计算圆周上的点
            double x = centerX + unitDx * radius;
            double y = centerY + unitDy * radius;

            return new Point(x, y);
        }

        #region 变量
        private Point mBefore = new Point(); //鼠标点击前位置
        private TouchPoint mBeforeTouchPoint; //触摸前位置
        private bool isMove = false; //鼠标是否移动
        private double rotateNumber; //旋转角度
        private Point centerP; //中心点位置
        private TouchPoint centerTouchPoint; //中心点位置
        private double rotateAng = 0; //旋转总角度
        #endregion

        #region 鼠标事件
        //点击中间图标让周围图标旋转一圈
        private void F_MouseDown(object sender, MouseButtonEventArgs e)
        {
            RotateAnimation(this, RotateNoumber);
            RotateAnimation((UIElement)sender, -RotateNoumber);
        }

        //选中一个图标鼠标按下事件
        private void Rotate_MouseDown(object sender, MouseButtonEventArgs e)
        {
            this.mBefore = e.GetPosition(this);

            this.MouseMove += Rotate_MouseMove;
        }

        private List<double> baseAngles = new List<double>();

        //拖动图标旋转事件
        private void Rotate_MouseMove(object sender, MouseEventArgs e)
        {
            Point mAfter = e.GetPosition(this);

            // 计算当前鼠标与中心点的角度（以正东方向为0°，逆时针增加）
            double dx = mAfter.X - centerP.X;
            double dy = -(mAfter.Y - centerP.Y); // Y轴翻转，屏幕坐标系向上为负
            double currentAngleRad = Math.Atan2(dy, dx); // 返回值范围 [-π, π]

            // 设置旋转角度为这个新角度
            ArrangeIcons(-currentAngleRad);

            ArrangeCenter(currentAngleRad);
            // 更新连线
            UpdateLines();

            // 可选：记录鼠标当前位置
            mBefore = mAfter;
        }

        private double? initialAngle; // 初始角度
        private void ArrangeCenter(double rotateAngcenter)
        {
            if (initialAngle == null)
            {
                initialAngle = rotateAngcenter; // 保存初始角度
            }
            var child = this.Children[0];
            if (child is FrameworkElement icon)
            {
                // 计算相对旋转角度
                double rotationAngle = -(rotateAngcenter - initialAngle.Value) * (180 / Math.PI); // 转换为度数，并反转方向

                // 应用旋转到目标元素（例如一个名为 middleElement 的UI元素）
                RotateTransform rotateTransform = new RotateTransform(rotationAngle, icon.ActualWidth / 2, icon.ActualHeight / 2);

                // 假设 middleElement 是你要旋转的中间空间的引用
                this.Children[0].RenderTransform = rotateTransform;
            }
               

        }

        private void ArrangeIcons(double rotateAng)
        {
            double centerX = this.ActualWidth / 2;
            double centerY = this.ActualHeight / 2;
            double radius = 150;

            int iconCount = this.Children.Count - 1;

            if (iconCount <= 0) return;

            double angleStep = 2 * Math.PI / 3;

            for (int i = 1; i < this.Children.Count; i++)
            {
                var child = this.Children[i];
                if (child is not FrameworkElement icon || (child is Ellipse ellipse && ellipse.Tag?.ToString() == "yuan")) continue;

                double baseAngle = (i - 1) * angleStep + rotateAng;
                double x = centerX + radius * Math.Cos(baseAngle);
                double y = centerY + radius * Math.Sin(baseAngle);

                Canvas.SetLeft(icon, x - icon.Width / 2);
                Canvas.SetTop(icon, y - icon.Height / 2);
            }
        }

        private void UpdateLines()
        {
            UIElementCollection children = this.Children;
            FrameworkElement centerIcon = children[0] as FrameworkElement;

            if (centerIcon == null) return;

            double centerX = Canvas.GetLeft(centerIcon) + centerIcon.Width / 2;
            double centerY = Canvas.GetTop(centerIcon) + centerIcon.Height / 2;
            int circleRadius = 80; // 确保这个值与AddLine中的一致

            foreach (var child in children)
            {
                if (child is Line line && line.Tag is FrameworkElement connectedIcon)
                {
                    double iconX = Canvas.GetLeft(connectedIcon) + connectedIcon.Width / 2;
                    double iconY = Canvas.GetTop(connectedIcon) + connectedIcon.Height / 2;

                    // 计算方向向量
                    double dx = iconX - centerX;
                    double dy = iconY - centerY;

                    // 计算圆周上的中断点
                    Point midPointOnCircle = GetPointOnCircle(centerX, centerY, circleRadius, dx, dy);

                    // 更新线段的起点和终点，使其通过圆周上的点
                    line.X1 = midPointOnCircle.X;
                    line.Y1 = midPointOnCircle.Y;
                    line.X2 = iconX;
                    line.Y2 = iconY;
                }
            }
        }

        #endregion

        #region Touch事件
        void F_TouchUp(object sender, TouchEventArgs e)
        {
            RotateAnimation(this, RotateNoumber);
            RotateAnimation((UIElement)sender, -RotateNoumber);
        }

        //TouchDown事件
        void Fotate_TouchDown(object sender, TouchEventArgs e)
        {
            this.mBeforeTouchPoint = e.GetTouchPoint(this);
            this.TouchMove += Rotate_TouchMove;
        }

        //TouchMove事件
        private void Rotate_TouchMove(object sender, TouchEventArgs e)
        {
            TouchPoint mAfterTouchPoint = e.GetTouchPoint(this); //获取鼠标移动过程中的坐标

            Point n1 = new Point(
                centerP.X - mBeforeTouchPoint.Position.X,
                centerP.Y - mBeforeTouchPoint.Position.Y
            );
            Point n2 = new Point(
                centerP.X - mAfterTouchPoint.Position.X,
                centerP.Y - mAfterTouchPoint.Position.Y
            );

            //n1*n2
            double n1n2 = n1.X * n2.X + n1.Y * n2.Y;
            //n1的模
            double n1mo = Math.Sqrt(Math.Pow(n1.X, 2) + Math.Pow(n1.Y, 2));
            //n2的模
            double n2mo = Math.Sqrt(Math.Pow(n2.X, 2) + Math.Pow(n2.Y, 2));

            //得带旋转角度
            double rotateNum = Math.Acos(n1n2 / (n1mo * n2mo));
            if (rotateNum.ToString() == "非数字")
            {
                rotateNum = 0;
            }
            //相对坐标原点位置
            Point potM = new Point();
            potM.X = mAfterTouchPoint.Position.X - centerP.X;
            potM.Y = centerP.Y - mAfterTouchPoint.Position.Y;
            Point potD = new Point();
            potD.X = mBeforeTouchPoint.Position.X - centerP.X;
            potD.Y = centerP.Y - mBeforeTouchPoint.Position.Y;

            //当鼠标移动超出边界时停止旋转
            if (
                mAfterTouchPoint.Position.X < 0
                || mAfterTouchPoint.Position.X > this.Width
                || mAfterTouchPoint.Position.Y < 0
                || mAfterTouchPoint.Position.Y > this.Height
            )
            {
                this.TouchMove -= Rotate_TouchMove;
            }
            else
            {
                if (GetcLockwise(potD, potM))
                {
                    rotateAng += rotateNum;
                }
                else
                {
                    rotateAng -= rotateNum;
                }
            }

            //执行旋转动画

            CanvansRotateAnimation(rotateAng);
            IconRotateAnimation(-rotateAng);
        }

        //释放父类
        private void Fp_MouseUp(object sender, MouseButtonEventArgs e)
        {
            this.MouseMove -= Rotate_MouseMove;
        }

        //TouchUp事件
        private void Rotate_TouchUp(object sender, TouchEventArgs e)
        {
            this.TouchMove -= Rotate_TouchMove;
        }
        #endregion

        #region 动画处理
        //等分圆周 显示中间和周围图标
        private void DivideCircleOnShowMenu()
        {
            //获取孩子节点
            UIElementCollection children = this.Children;

            FrameworkElement f;

            //外圆半径
            double outCircleRadius = this.Width / 2 - IconWidthAndHeight / 2;

            //平分度数
            double divideEquallyAngle = 360 / (children.Count - 1);
            //divideEquallyAngle = 40;
            for (int i = 0; i < children.Count; i++)
            {
                f = children[i] as FrameworkElement;

                //第一个中间图标
                if (i == 0)
                {
                    if (ShowMenu)
                    {
                        f.SetValue(Canvas.TopProperty, outCircleRadius);
                        f.SetValue(Canvas.LeftProperty, outCircleRadius);
                        if (OperateType == OperateEnum.MouseOperate)
                        {
                            f.MouseDown += F_MouseDown;
                        }
                        else
                        {
                            f.TouchUp += F_TouchUp;
                        }
                    }
                    else
                    {
                        f.SetValue(Canvas.TopProperty, outCircleRadius - f.Width / 2);
                        f.SetValue(Canvas.LeftProperty, outCircleRadius - f.Width / 2);
                        f.Visibility = Visibility.Hidden;
                    }
                }
                else
                {
                    //内角度数  角度转换为弧度
                    double innerAngle = divideEquallyAngle * (i - 1) * Math.PI / 180;

                    //TOP距离
                    double topHeight = outCircleRadius - Math.Cos(innerAngle) * outCircleRadius;

                    //Left距离
                    double leftWidth = Math.Sin(innerAngle) * outCircleRadius;

                    if (innerAngle <= 180)
                    {
                        f.SetValue(Canvas.TopProperty, topHeight);
                        f.SetValue(Canvas.LeftProperty, outCircleRadius + leftWidth);
                    }
                    if (innerAngle > 180)
                    {
                        f.SetValue(Canvas.TopProperty, topHeight);
                        f.SetValue(Canvas.LeftProperty, outCircleRadius - leftWidth);
                    }

                   
                }
            }

           

         
        }

        /// <summary>
        /// 获取顺时针还是逆时针
        /// </summary>
        /// <param name="potD">按下坐标</param>
        /// <param name="potM">移动坐标</param>
        /// <returns>True：顺，False：逆</returns>
        private bool GetcLockwise(Point potD, Point potM)
        {
            if (potM.Y >= 0 && potD.Y >= 0) //一二象限
            {
                return potM.X >= potD.X;
            }
            if (potM.Y < 0 && potD.Y < 0) //三四象限
            {
                return potM.X <= potD.X;
            }
            if (potM.X >= 0 && potD.X >= 0) //一四象限
            {
                return potM.Y <= potD.Y;
            }
            if (potM.X < 0 && potD.X < 0) //二三象限
            {
                return potM.Y >= potD.Y;
            }
            else
            {
                return true;
            }
        }

        //图标绕中心点旋转
        private void OnShowMenuAnimation(double rotateNumber)
        {
            RotateTransform rtf = new RotateTransform();
            UIElementCollection children = this.Children;
            FrameworkElement f;
            //图标宽高
            double iconWidthAndHeight = 50;
            double left;
            double top;
            //中心点
            double centerPointX = this.Width / 2 - iconWidthAndHeight / 2;
            double centerPointY = this.Height / 2 - iconWidthAndHeight / 2;

            //每个图标相对中心点的点
            double relativePointX;
            double relativePointY;

            for (int i = 0; i < children.Count; i++)
            {
                f = children[i] as FrameworkElement;
                //不是第一个图标时
                if (i != 0)
                {
                    left = (double)f.GetValue(Canvas.LeftProperty);
                    top = (double)f.GetValue(Canvas.TopProperty);

                    relativePointX = (centerPointX - left) / iconWidthAndHeight;
                    relativePointY = (centerPointY - top) / iconWidthAndHeight;

                    f.RenderTransform = rtf;
                    f.RenderTransformOrigin = new Point(relativePointX, relativePointY);
                }
            }
            //定义动画路径和事件
            DoubleAnimation dbAnimation = new DoubleAnimation(
                0,
                rotateNumber,
                new Duration(TimeSpan.FromSeconds(RotateSpeed))
            );
            //定义动画次数
            dbAnimation.RepeatBehavior = new RepeatBehavior(RotateNoumber);
            //开始动画
            rtf.BeginAnimation(RotateTransform.AngleProperty, dbAnimation);
        }

        //图标自旋转
        private void IconRotateAnimation(double rotateNumber)
        {
            // 检查 rotateNumber 是否为 NaN 或 Infinity
            if (double.IsNaN(rotateNumber) || double.IsInfinity(rotateNumber))
            {
                rotateNumber = 0;
            }

            RotateTransform rtf = new RotateTransform();
            UIElementCollection children = this.Children;

            for (int i = 0; i < children.Count; i++)
            {
                FrameworkElement f = children[i] as FrameworkElement;
                if (f != null)
                {
                    f.RenderTransform = rtf;
                    f.RenderTransformOrigin = new Point(0.5, 0.5);
                }
            }

            // 创建动画
            DoubleAnimation dbAnimation = new DoubleAnimation(
                0,
                rotateNumber,
                new Duration(TimeSpan.FromSeconds(0)) // 可以改为 0.3 秒实现平滑动画
            );

            // 启动动画
            rtf.BeginAnimation(RotateTransform.AngleProperty, dbAnimation);
        }

        //canvans旋转
        private void CanvansRotateAnimation(double rotateNumber)
        {
            if (double.IsNaN(rotateNumber) || double.IsInfinity(rotateNumber))
            {
                rotateNumber = 0;
            }
            if (rotateNumber.ToString() == "非数字")
            {
                rotateNumber = 0;
            }
            RotateTransform rtf = new RotateTransform();
            this.RenderTransform = rtf;
            this.RenderTransformOrigin = new Point(0.5, 0.5);

            //定义动画路径和事件
            DoubleAnimation dbAnimation = new DoubleAnimation(
                0,
                rotateNumber,
                new Duration(TimeSpan.FromSeconds(0.0))
            );

            //开始动画
            rtf.BeginAnimation(RotateTransform.AngleProperty, dbAnimation);
        }

        //canvans旋转
        private void RotateAnimation(UIElement uIelement, double rotateNumber)
        {
            RotateTransform rtf = new RotateTransform();
            uIelement.RenderTransform = rtf;
            uIelement.RenderTransformOrigin = new Point(0.5, 0.5);

            //定义动画路径和事件
            DoubleAnimation dbAnimation = new DoubleAnimation(
                0,
                rotateNumber,
                new Duration(TimeSpan.FromSeconds(RotateSpeed))
            );

            //开始动画
            rtf.BeginAnimation(RotateTransform.AngleProperty, dbAnimation);
        }
        #endregion
        #endregion
    }
}
